package com.wy.model;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.Objects;

import com.wy.annotation.CheckAdd;
import com.wy.annotation.CheckUpdate;
import com.wy.annotation.Sort;
import com.wy.enums.TipEnum;
import com.wy.result.Result;
import com.wy.result.ResultException;
import com.wy.utils.MapUtils;
import com.wy.utils.MapUtils.MapBuilder;
import com.wy.utils.StrUtils;

/**
 * 在通用新增的basecrl中会调用,校验新增和全字段修改参数,只检查非空
 * @description 
 * @author ParadiseWY
 *	@date 2019年4月11日 下午2:16:59
 * @git {@link https://github.com/mygodness100}
 */
public abstract class AbsModel<T> extends AbsPager implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * 新增数据时是否检查参数非空,只能检查非空
	 * @return 默认检查
	 */
	public boolean checkAdd() {
		return true;
	}

	public Map<String, Object> checkAdd(T t) {
		Class<? extends Object> clazz = t.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			if (Modifier.isStatic(field.getType().getModifiers())
					|| Modifier.isFinal(field.getType().getModifiers())
					|| field.getType().isEnum()) {
				continue;
			}
			try {
				field.setAccessible(true);
				if (field.isAnnotationPresent(CheckAdd.class)) {
					if (Objects.isNull(field.get(t))) {
						CheckAdd checkAdd = field.getAnnotation(CheckAdd.class);
						if (checkAdd.error() == TipEnum.UNKNOWN) {
							throw new ResultException(field.getName() + checkAdd.value());
						} else {
							throw new ResultException(checkAdd.error());
						}
					}
				}
				if (field.isAnnotationPresent(Sort.class)) {
					// 此处code=2表示需要排序,其他code预留
					MapBuilder builder = MapUtils.getBuilder("code", 2);
					Sort sort = field.getAnnotation(Sort.class);
					if (StrUtils.isNotBlank(sort.value())) {
						builder.add("sort", sort.value());
					} else {
						builder.add("sort", "sort");
					}
					return builder.build();
				}
			} catch (IllegalArgumentException | IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	/**
	 * 全字段更新时是否检查参数,只能检查非空,若有其他需求可重写
	 * @return 默认检查
	 */
	public boolean checkUpdate() {
		return true;
	}

	public Result checkUpdate(T t) {
		Class<? extends Object> clazz = t.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			if (Modifier.isStatic(field.getType().getModifiers())
					|| Modifier.isFinal(field.getType().getModifiers())
					|| field.getType().isEnum()) {
				continue;
			}
			if (field.isAnnotationPresent(CheckAdd.class)
					|| field.isAnnotationPresent(CheckUpdate.class)) {
				field.setAccessible(true);
				try {
					if (Objects.isNull(field.get(t))) {
						CheckAdd checkAdd = field.getAnnotation(CheckAdd.class);
						CheckUpdate checkUpdate = field.getAnnotation(CheckUpdate.class);
						if (checkUpdate != null) {
							if (checkUpdate.error() == TipEnum.UNKNOWN) {
								return Result.error(field.getName() + checkUpdate.value());
							} else {
								return Result.result(checkUpdate.error());
							}
						} else {
							if (checkAdd.error() == TipEnum.UNKNOWN) {
								return Result.error(field.getName() + checkAdd.value());
							} else {
								return Result.result(checkAdd.error());
							}
						}
					}
				} catch (IllegalArgumentException | IllegalAccessException e) {
					e.printStackTrace();
				}
			}
		}
		return null;
	}
}